package main

import(
	"reflect"
	"errors"
	"fmt"
//	"strings"
	"github.com/robertkrimen/otto"
)

var m map[string]interface{}
var vmconsole *otto.Otto
func init(){
	m= map[string]interface{} {
		"exit":APP_Interface_exit,
		"help":APP_Interface_help,
		"ping":APP_Interface_ping,
		"VMstart":APP_Interface_VM_Console_Start,
		"vm":APP_Interface_VM,
		"user":APP_Interface_user,
		"test":APP_Interface_Test,
		"bind":APP_Interface_bind,
		"setos":APP_Interface_setos,
	}
	vmconsole=otto.New()
	vmconsole.Run(File_Read_All("dll/console/index.js"))
	Setfunction(vmconsole)
}
func _pt(str ...string) { Print_(console_type_default|16, str...) }
func _ptc(str ...string) { Print_(console_type_console|16, str...) }
func APP_Interface_exit(line_ ...string)string{
	go func(){Sleep(2000);_pt("send Exit signal")
	exit_t = true
	listener.Close()}()
	return "send Exit signal"
}
func APP_Interface_help(str ...string)(_c_out_c string){
	_pt:=func(str ...string){for i:=0;i<len(str);i++{_c_out_c=_c_out_c+str[i]+"\n"}}
	_pt("help list:")
	return
}
func APP_Interface_ping(line ...string)string{
	if line[1] == "" {
		return ("plese enter UID")
	} else {
		timex:=Ping_(line[1],nil,2000)
		if(timex==0){return("Ping time out")}else{return("ping time:" + ToString(timex) + "ms")}
		
	}
}
func APP_Interface_user(line_ ...string) (_c_out_c string){
	_pt:=func(str ...string){for i:=0;i<len(str);i++{_c_out_c=_c_out_c+str[i]+"\n"}}
	line:=resize(line_,5)//重定义数组大小
	if(line[1]=="list"){
		list := get_all_online()
			_pt("user                 sock")
			for i := 0; i < len(list); i++ {
				_pt(fmt.Sprintf("%s     %d", list[i].name, list[i].tcp))

			}
		return 
	}else if(line[1]=="send"){
		s, _ := getsock(UID_get_sock(line[2]))
			t := ToInt64(line[3])//strconv.ParseInt((string)(line[2]), 10, 10)
			x := ints_to_Bytes((uint8)(t))
			l,err:=s.Write(byte_add_to_bytes(x, []byte(line[4])))
			if(err!=nil){return err.Error()}else{return ToString(l)}
	}else if(line[1]=="add"){
		u := line[2] //getsock(UID_get_sock())
		p := line[3]

		if len(u) <6 {
			return ("user name length error ,must len >6")
		}else if(len(u)>16){
			return ("user name length error ,must len <16")
		} else {
			u=Completion_id(u)
			sql := "insert into userlist(mail,name,UID,pass)values('','','" + u + "','" + MD5("Machine"+p)[:16] + "')"
			_,err:=Exec_SQL(sql)
			if(err!=nil){return err.Error()}else{return "true"}
		}
	}else{

	}


	
	return "error"
}
func APP_Interface_VM(line_ ...string)(_c_out_c string){
	_pt:=func(str ...string){for i:=0;i<len(str);i++{_c_out_c=_c_out_c+str[i]+"\n"}}
	line:=resize(line_,5)//重定义数组大小
	if(line[1]=="list"){//取已经加载的列表
		name,version,size,enable:=Console_Get_os_list()
				_pt("name				version 	size		status	")
				m:=[]string{"B","KB","MB","GB","TB"}
				for i:=0;i<len(name);i++{out:=""
					if(len(name[i])>16){out=name[i][:16]}else{out=name[i]+Make_Txt("	",(5-len(name[i])/4))}
					if(len(version[i])>16){out=out+version[i][:16]}else{out=out+version[i]+Make_Txt("	",(3-len(version[i])/4))}
					t:=0;s:=0.0
					if(size[i]>=1024){t=t+1;s:=size[i]/1024;for s>=1024 {t=t+1;s=s/1024};}else{s=float64(size[i])}
					str:=fmt.Sprintf("%.2f", s)+m[t]
					if(len(str)>16){out=out+str[:16]}else{out=out+str+Make_Txt("	",(3-len(str)/4))}
					if(enable[i]==true){str="EN"}else{str="OFF"}
					if(len(str)>8){out=out+str[:8]}else{out=out+str+Make_Txt("	",(2-len(str)/4))}
					_pt(out);return}
	}else if(line[1]=="enable"){//启用OS
		oslist[line[2]].Enable()
	}else if(line[1]=="disable"){//禁用OS
		oslist[line[2]].Disable()
	}else if(line[1]=="reload"){//重载包
		//if(Interface_Reset(line[2])){_pt("true")}else{_pt("false")}
	}else if(line[1]=="load"){//加载包
		if(Reload_OS(line[2])){_pt("true")}else{_pt("false")}
	}else if(line[1]=="unload"){//卸载包
		unload_OS(line[2])
		return "OK"
	}else{
		return "help"
	}
	return
}
func APP_Interface_VM_Console_Start(line_ ...string)string{
	//启动一个JS虚拟机控制台
	line:=resize(line_,5)//重定义数组大小
	if(line[1]==""){return ("please input os name")}
	CreatVM("console",0,line[1])
	r:=Interface_console("console")
	for{
		//fmt.Scanln(&line[0], &line[1], &line[2], &line[3])
		str:=""
		fmt.Print("console@VM("+line[2]+") >")
		/*fmt.Scanf("%s\n", &str)*/
		str=Cli_read_ToString()
		if(str=="exit"){return ""}else if(str==""){ }else{
			result,err:=r(str)
			if(err!=nil){return("[ error ]" + err.Error())}else{	
				s,_:=result.ToString()
				if(s=="" || s=="undefined"){ }else{return(s)
				}
			}
		}
	}
	


	//return "help"
}
func APP_Interface_Test(line_ ...string)string{
	Print_(3,line_...)
	return "is ok"
}
func APP_Interface_bind(line_ ...string)(_c_out_c string){
	_pt:=func(str ...string){for i:=0;i<len(str);i++{_c_out_c=_c_out_c+str[i]+"\n"}}
	line:=resize(line_,5)
	if(line[1]==""){_pt("please input userid");return}
	if(line[2]==""){_pt("please input machineid");return}
	if(line[3]==""){_pt("please input type");return}
	if(line[4]==""){_pt("please input showname");return}
	user:=line[1]
	macid:=line[2]
	type_:=line[3]
	name:=line[4]
	if(len(user)>16){_pt("please input user len < 16 ");return}
	if(len(user)<6){_pt("please input user len > 6  ");return}
	user=Completion_id(user)
	SQL:="INSERT INTO `relation` (`uid`, `machineID`, `title`, `type`) VALUES (\""+user+"\", \""+macid+"\", \""+name+"\", \""+type_+"\")"
	_,err:=Exec_SQL(SQL)
	if(err!=nil){_pt("Error:"+err.Error())}else{_pt("add done")}
	return 
}
func APP_Interface_setos(line_ ...string)(_c_out_c string){
	_pt:=func(str ...string){for i:=0;i<len(str);i++{_c_out_c=_c_out_c+str[i]+"\n"}}
	line:=resize(line_,5)
	if(line[1]==""){_pt("please input machineid");return}
	if(line[2]==""){_pt("please input osname");return}
	macid:=line[1]
	osname:=line[2]
	if(len(macid)!=16){_pt("mac id len=16");return}
	//if(osname)
	/*if(len(user)>16){_pt("please input user len < 16 ");return}
	if(len(user)<6){_pt("please input user len > 6  ");return}
	user=Completion_id(user)*/
	SQL:="INSERT INTO `os_bind` (`UID`, `osname`) VALUES (\""+macid+"\", \""+osname+"\")"
	_,err:=Exec_SQL(SQL)
	if(err!=nil){_pt("Error:"+err.Error())}else{_pt("add done")}
	return 
}
func Call( name string, params ...interface{}) (result []reflect.Value, err error) {
	var x []reflect.Value
	if(m[name]==nil){
		//Value=
		v,errx:=vmconsole.Call(name,params[0],params[1:]...)
		
		if(errx!=nil){err=errors.New("Not Have this func."+errx.Error());return}else{
			s,_:=v.ToString()
			if(s=="" || s=="undefined"){s=""}
			//result:=
			//result=x
				//result=reflect.ValueOf("") }else{result=reflect.ValueOf(s)}
			return append(x,reflect.ValueOf(s)),nil
		}
	}
	
	f := reflect.ValueOf(m[name])
	//if(f==nil){err=errors.New("The number of params is not adapted.");return}
    /*if len(params) != f.Type().NumIn() {
        err = errors.New("The number of params is not adapted.")
        return
	}*/
	/*in := make([]reflect.Value, len(params))
    for k, param := range params {
        in[k] = reflect.ValueOf(param)
	}*/
	var paramSlice []string
    for _, param := range params {
        switch v := param.(type) {
        case string:
            paramSlice = append(paramSlice, v)
        case int:
            //strV := strconv.FormatInt(int64(v), 10)
            //paramSlice = append(paramSlice, strV)
        default:
            panic("params type not supported")
        }

    }
	
	ii:=0
	for i:=len(paramSlice)-1;i>=0;i--{if(paramSlice[i]!=""){ii=i;break}}
	for i:=0;i<ii+1;i++ {x=append(x,reflect.ValueOf(paramSlice[i]))}
	//x=append(x,reflect.ValueOf("2"))
    result = f.Call(x)
    return
}

func resize(line []string,l int)[]string{
	
	if(len(line)<l){
		k:=make([]string,l-len(line))
		return append(line,k...)
	}else{
		return line[:l]
	}
}